package com.warrior.service;

import com.warrior.Exception.ProjectException;
import com.warrior.configer.ConfigHelper;
import com.warrior.entity.VerifyCodeEntity;
import com.warrior.respository.IVerifyCodeRepository;
import com.warrior.util.CommonUtils;
import com.warrior.util.DateUtil;
import com.warrior.util.GenerateCodeUtil;
import com.warrior.util.SMSMessageBaseTools;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * Created by Shawn on 2017/3/20.
 */
@Service
public class VerifyCodeService {

    private static final Logger logger = LogManager.getLogger(VerifyCodeService.class.getName());

    private static final String VERIFYCODE_LENGTH = ConfigHelper.getConfig().getString("VERIFYCODE.LENGTH");

    private static final String VERIFYCODE_EXPIRETIME = ConfigHelper.getConfig().getString("VERIFYCODE.EXPIRETIME");


    @Autowired
    private IVerifyCodeRepository verifyCodeRepository;


    @Transactional
    public void saveNewVerifyCode(String mobile,String code) {
        if (logger.isDebugEnabled()) {
            logger.debug("saveNewVerifyCode(String mobile={}) - start", mobile); //$NON-NLS-1$
        }

        List<VerifyCodeEntity> verifyCodeEntityByMobile = this.verifyCodeRepository.findVerifyCodeEntityByMobileOrderByCreatedAtDesc(mobile);
        if (null != verifyCodeEntityByMobile) {
            //生成时发现之前有保存数据,则删除记录
            for (int i = 0; i < verifyCodeEntityByMobile.size(); i++) {
                this.deleteCodeById(verifyCodeEntityByMobile.get(i).getId());
            }
        }
        DateUtil dateUtil = new DateUtil();
        VerifyCodeEntity verifyCodeEntity = new VerifyCodeEntity();
        verifyCodeEntity.setId("V-" + UUID.randomUUID().toString().replace("-", ""));
        verifyCodeEntity.setCode(code);
        verifyCodeEntity.setMobile(mobile);
        verifyCodeEntity.setCreatedBy("-99999");
        verifyCodeEntity.setUpdateBy("-99999");
        verifyCodeEntity.setUpdateAt(dateUtil.Date2Timestamp(new Date()));
        verifyCodeEntity.setCreatedAt(dateUtil.Date2Timestamp(new Date()));
        this.verifyCodeRepository.save(verifyCodeEntity);

        if (logger.isDebugEnabled()) {
            logger.debug("saveNewVerifyCode(String) - end"); //$NON-NLS-1$
        }
    }


    @Transactional
    public void deleteCodeById(String id) {
        if (logger.isDebugEnabled()) {
            logger.debug("deleteCodeById(String id={}) - start", id); //$NON-NLS-1$
        }

        this.verifyCodeRepository.delete(id);

        if (logger.isDebugEnabled()) {
            logger.debug("deleteCodeById(String) - end"); //$NON-NLS-1$
        }
    }


    @Transactional
    public VerifyCodeEntity findCodeByMobile(String mobile) throws ProjectException {
        if (logger.isDebugEnabled()) {
            logger.debug("findCodeByMobile(String mobile={}) - start", mobile); //$NON-NLS-1$
        }

        VerifyCodeEntity verifyCodeEntity;
        List<VerifyCodeEntity> verifyCodeEntityByMobile = this.verifyCodeRepository.findVerifyCodeEntityByMobileOrderByCreatedAtDesc(mobile);
        if (null != verifyCodeEntityByMobile) {
            //由于添加的时候做了唯一性判断,这里取第一条就可以了
            verifyCodeEntity = verifyCodeEntityByMobile.get(0);
        } else {
            throw new ProjectException("该用户未发送短信");
        }

        if (logger.isDebugEnabled()) {
            logger.debug("findCodeByMobile(String) - end"); //$NON-NLS-1$
        }
        return verifyCodeEntity;
    }


    /**
     * 验证短信码
     *
     * @param mobile
     * @param code
     * @return
     */
    @Transactional
    public boolean validateVerifyCode(String mobile, String code) throws ProjectException {
        if (logger.isDebugEnabled()) {
            logger.debug("validateVerifyCode(String mobile={}, String code={}) - start", mobile, code); //$NON-NLS-1$
        }

        Boolean flag = false;
        VerifyCodeEntity codeByMobile = this.findCodeByMobile(mobile);
        if (null == codeByMobile) {
            throw new ProjectException("未找到该手机号发送的短信内容");
        }
        //先验证是否过期
        Date time = new Date();
        long nowTime = time.getTime();
        long sendTime = codeByMobile.getCreatedAt().getTime();
        if (nowTime - sendTime < Long.parseLong(VERIFYCODE_EXPIRETIME)) {
            if (code.equals(codeByMobile.getCode())) {
                // 验证通过,删除记录
                this.deleteCodeById(codeByMobile.getId());
                flag = true;
            } else {
                throw new ProjectException("验证码错误");
            }
        }else {
            // 防止数据过多,删除记录
            this.deleteCodeById(codeByMobile.getId());
            throw new ProjectException("验证码过期");
        }

        if (logger.isDebugEnabled()) {
            logger.debug("validateVerifyCode(String, String) - end"); //$NON-NLS-1$
        }
        return flag;
    }

    /**
     * 发送验证码
     * @param mobile 手机号
     */
    public void sendVerifyCode(String mobile){
        SMSMessageBaseTools smsMessageBaseTools = new SMSMessageBaseTools(ConfigHelper.getConfig().getString("SMS.URL"),ConfigHelper.getConfig().getString("SMS.ID"),ConfigHelper.getConfig().getString("SMS.ACCOUNT"),ConfigHelper.getConfig().getString("SMS.PWD"));
        try {
            String randomInt = GenerateCodeUtil.randomInt(CommonUtils.String2Int(ConfigHelper.getConfig().getString("VERIFYCODE.LENGTH")));
            this.saveNewVerifyCode(mobile,randomInt);
            smsMessageBaseTools.messageSendTools(ConfigHelper.getConfig().getString("SMS.SIGN")+"您的验证码是："+randomInt+"，有效期5分钟，请尽快在页面中提交验证码完成验证。", mobile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }




}
